#include "../common.h"
#include <simplot.h>


class TestTaskDel {
public:
	int a = 5;
};

namespace _TestService {

void fn(TaskCtx<int> *arg) {
	int n = arg->ctx;
	while (!Task::isShutdown()) {
		Serial.println(" task run statu:");
		Task::delay(10000 + n * 100);
	}
	throw "xxxxx";
}

void fn2(TaskCtx<void*> *ctx) {
	while (!Task::isShutdown()) {
		Serial.println(" task2 run statu:");
		Task::delay(10000);
	}
	throw "xxxxx";
}

void fn3(TaskCtx<TestTaskDel*> *ctx) {
	Serial.println(ctx->ctx->a);
	ctx->ctx->a = 555;
}

void testTask() {
	int t = 10000;
	TaskCtx<int> *ctx = new TaskCtx<int>(1);
	Task::run(&_TestService::fn, ctx);
	while (t-- > 0) {
		//不能一次提交太多任务，可能底层队列没做长度判断，创建太多造成内存不足
		if (t % 50 == 0) {
			Serial.println(t);
			delay(5000);
		}
	}

//
//	xTaskCreateUniversal(
//			&_TestService::fn2,
//			"TEST2",
//			1024*2,
//			 n3,
//			_taskPriority++,
//			NULL, 1);a
}

class Popole {
public:
	std::string name;
	std::string age;

	AIGC_JSON_HELPER(name, age) //成员注册
};
class Student: Popole {
public:
	std::string depart;
	int grade;AIGC_JSON_HELPER(depart, grade) //成员注册
	AIGC_JSON_HELPER_BASE((Popole*)this) //基类注册
};
class Class {
public:
	std::string name;
	int test;
	std::list<Student> students;
	Popole master;

	AIGC_JSON_HELPER(name, test, students, master) //成员注册

	~Class() {
	}
};

std::string sjson = R"({
    "name": "yaronzz", "master" : {"name" : "刘老师", "age" : 35}, "students" : [ {"name" : "张小明", "age" : 5, "grade" : 3, "depart" : "小学"}, {"name" : "张小红", "age" : 7, "grade" : 3, "depart" : "小学"} ]
})";

void testJson() {
	Class my;

	JsonHelper::JsonToObject(my, _TestService::sjson);

	Serial.println(my.name.c_str());
	Serial.println(my.master.name.c_str());

	std::string jsonstr;
	JsonHelper::ObjectToJson(my, jsonstr);
	Serial.println("ObjectToJson");

	Serial.println(jsonstr.c_str());
}

void testRadom() {
	std::vector<RandomRatio<int>> ratios = { { 0, 20 }, { 1, 80 }, };
	while (true) {
		delay(2000);
		int ret = random(ratios);
		Serial.println(ret);
	}
}

//P2PService p2pService;
//void keepAliveTimer(void *arg) {
//	p2pService.keepAlive();
//}
//void event_serial_message(TaskCtx<String> *arg) {
//	String cmd = arg->ctx;
//
//	if (cmd.startsWith("startServer ") > 0) {
//		const String addr = AddressTool::toIp(cmd, "startServer ");
//		const int port = AddressTool::toPort(cmd);
//		p2pService.startServer(addr, port);
//		return;
//	}
//
//	if (cmd.startsWith("g") || cmd.startsWith("r")) {
//		std::string str = cmd.c_str();
//		Serial.println(str.c_str());
//		p2pService.sendToProxyServer(str);
//		return;
//	}
//
//	if (cmd.startsWith("connect ") > 0) {
//		const String addr = AddressTool::toIp(cmd, "connect ");
//		const int port = AddressTool::toPort(cmd);
//		p2pService.connect(addr, port);
//		return;
//	}
////	if (cmd.startsWith("sendToClient") > 0) {
////		const String sid = AddressTool::toArg(cmd, "sendToClient");
////		const std::string str = "send message ";
////		p2pService.sendToClient(sid, str);
////		return;
////	}
//
//	if (cmd.startsWith("udp") <= 0) {
//		return;
//	}
//
//	int addressStartIndex = 3;
//	int addressEndIndex = cmd.indexOf(":");
//	const String addr = cmd.substring(addressStartIndex + 1, addressEndIndex);
//	const int port = cmd.substring(addressEndIndex + 1).toInt();
//	AuPacketHandlerFunction cb = ([](AsyncUDPPacket packet) {
//		char c[packet.length()];
//		memmove(c, packet.data(), packet.length());
//		String cmd(c);
//		if (cmd.startsWith("connect:")) {
//			const String addr = AddressTool::toIp(cmd, "connect:");
//			const int port = AddressTool::toPort(cmd);
//			p2pService.connect(addr, port);
//		}
//		Serial.println(cmd);
//		Serial.print(packet.remoteIP());
//		Serial.print(":");
//		Serial.println(packet.remotePort());
//	});
//	p2pService.connectProxyServer(addr, port, cb);
//
//}
void testJsonRepository() {
	WifiConfig wifiConfig("a", "b"), wifiConfig2("a", "b");
 	GET_BEAN(MODEL_REPOSITORY,RepositoryService)->load(wifiConfig);
	Serial.println(wifiConfig.passwd.c_str());

	wifiConfig.passwd = "a";
	GET_BEAN(MODEL_REPOSITORY,RepositoryService)->save(wifiConfig);

	GET_BEAN(MODEL_REPOSITORY,RepositoryService)->load(wifiConfig);
	Serial.println(wifiConfig.passwd.c_str());

	wifiConfig2.id = "xxxxx";
	GET_BEAN(MODEL_REPOSITORY,RepositoryService)->load(wifiConfig2);
	Serial.println(wifiConfig2.passwd.c_str());

}

}

class PWMConfig {
public:
	double freq = 2000;
	uint32_t delay = 80;
	uint8_t resolution = 8;

	AIGC_JSON_HELPER(freq,delay)
};

const uint channel = 0;
void testPWM() {
	PWMConfig pwmConfig;
	double ret = ledcSetup(channel, pwmConfig.freq, pwmConfig.resolution);
	ledcAttachPin(GPIO_NUM_16, channel);
	Serial.println(ret);
}
cmd_injection_handle(TEST2,event_serial_message_test_,PWMConfig* pwmConfig,PWMConfig) {
	double ret = ledcSetup(channel, pwmConfig->freq, pwmConfig->resolution);
	Serial.println(ret);
}
void TestService::loop() {

// 	for (int dutyCycle = 0; dutyCycle <= 2^8-1; dutyCycle = dutyCycle + 5) {
//		ledcWrite(channel, dutyCycle);
//		plot(dutyCycle, ledcReadFreq(channel));
//		delay(pwmConfig.delay);
//	}
// 	for (int dutyCycle = 2^8-1; dutyCycle >= 0; dutyCycle = dutyCycle - 5) {
//		ledcWrite(channel, dutyCycle);
//		plot(dutyCycle, ledcReadFreq(channel));
//		delay(pwmConfig.delay);
//	}
}

class TestDecode {
public:
	int a = 2000;AIGC_JSON_HELPER(a)
};

cmd_injection_handle(TEST1,textJsonDecode,TestDecode * obj,TestDecode) {
	Serial.println(obj->a);
}

event_injection_handle(EVENT_SERIAL_MESSAGE, event_serial_message2,TaskCtx<String> *ctx) {
//	RepositoryService *service = GET_BEAN(MODEL_REPOSITORY, RepositoryService);
//	Serial.println(service->canOpen);
//	Serial.println(GET_BEAN(MODEL_REPOSITORY,RepositoryService)==App.pRepositoryService);
}

event_injection_handle(EVENT_SERIAL_MESSAGE, event_serial_message3,TaskCtx<String> *ctx) {
//	String path = ctx->ctx;
//	String wstr = "text....";
//	String rstr;
//	App.pRepositoryService->save(wstr, path);
//	App.pRepositoryService->load(rstr, path);
//	Serial.println(rstr);
}

void TestService::start() {
	//testPWM();
	//AppContext::eventService.registerHandle(EVENT_SERIAL_MESSAGE, &_TestService::event_serial_message);
	//_TestService::testUdpServer();
	//Timer keepAliveTimer = Timer(1000 * 60, _TestService::keepAliveTimer);
	//keepAliveTimer.startPeriodic();
	//_TestService::testRadom();
	//Serial.println(xPortGetCoreID());

//	TaskCtx<TestTaskDel*> *ctx = new TaskCtx<TestTaskDel*>(new TestTaskDel,true);
//	ctx->initTaskSize(2);
//	Task::run(&_TestService::fn3, ctx);
//	Task::run(&_TestService::fn3, ctx);
//	String path = "/test1";
//	String wstr = "text....";
//	String rstr;
//	App.pRepositoryService->save(wstr, path);
//	App.pRepositoryService->load(rstr, path);
//	Serial.println(rstr);
}

